﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace CodeContrib
{
	public static class ObjectExtensions
	{
		public static T Clone<T>(this T obj)
		{
			if (!typeof (T).IsSerializable)
			{
				throw new ArgumentException("The type must be serializable.", "obj");
			}

			if (ReferenceEquals(obj, null))
			{
				return default(T);
			}

			IFormatter formatter = new BinaryFormatter();

			using (Stream stream = new MemoryStream())
			{
				formatter.Serialize(stream, obj);
				stream.Seek(0, SeekOrigin.Begin);

				return (T)formatter.Deserialize(stream);
			}
		}

		public static T GetValueOrDefault<T>(this T value) where T : class
		{
			return GetValueOrDefault(value, default(T));
		}

		public static T GetValueOrDefault<T>(this T value, T defaultValue) where T : class
		{
			return value ?? defaultValue;
		}
	}
}